package com.oa.web;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;



public abstract class AbstractServices extends HibernateDaoSupport {
	
	public PageModel searchPaginated(String hql){
		return searchPaginated(hql, null);
	}
	
	public PageModel searchPaginated(String hql,Object[] values){
		return searchPaginated(hql, values, SystemContext.getOffset(), SystemContext.getPagesize());
	}
		
	public PageModel searchPaginated(String hql,Object value,int offset,int pagesize){
		return searchPaginated(hql, new Object[]{value}, offset, pagesize);
	}
	public List query(final String hql, final int currentpage,
			final int pageunit, final Object... Params) throws Exception {
		return (List) this.getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query q = session.createQuery(hql);
						if (Params != null && Params.length > 0) { 
							int i = 0;
							for (Object obj : Params) {
								if (obj != null) {
									q.setString(i, obj.toString());
									i++;
								}
							}
						}
						try {
							page(q, currentpage, pageunit);
						} catch (Exception e) {
							e.printStackTrace();
						}
						List list = q.list();
						return list;
					}
				});
	}
	/**
	 * 
	 *
	 *
	 */
	public Query page(final Query q, final int currentpage, final int pageunit)
	throws Exception {
	return (Query) this.getHibernateTemplate().execute(
			new HibernateCallback() {
				public Object doInHibernate(Session session)
						throws HibernateException, SQLException {
					q.setFirstResult((currentpage - 1) * pageunit);
					q.setMaxResults(pageunit);
					return q;
				}
			});
	}
	public Object queryAggregation(final String hql, final Object... Params)
	throws Exception {
	return this.getHibernateTemplate().execute(new HibernateCallback() {
		public Object doInHibernate(Session session)
				throws HibernateException, SQLException {
			Query q = session.createQuery(hql);
			if (Params != null && Params.length > 0) {
				int i = 0;
				for (Object obj : Params) {
					if (obj != null) {
						q.setString(i, obj.toString());
						i++;
					}
				}
			}
			return q.uniqueResult();
		}
	});
	}
	/**
	 */
	public PageModel searchPaginated(String hql,Object[] values,int offset,int pagesize){
		String countHql = getCountQuery(hql);
		Query query=getQuery(countHql,values);
	
		int total = ((Long)query.uniqueResult()).intValue();	
		query =getQuery(hql,values);
		query.setFirstResult(offset);
		query.setMaxResults(pagesize);
		List datas = query.list();
	
		PageModel pm = new PageModel();
		pm.setList(datas);
		pm.setTotalRecords(total);
		pm.setPageNo(offset);
		pm.setPageSize(pagesize);
		return pm;
	}
	/**
	 * @param hql
	 * @return
	 */
	private String getCountQuery(String hql){
		int index = hql.indexOf("from");
		if(index != -1){
			return "select count(*) " + hql.substring(index);
		}
		throw new RuntimeException();
	
	}
	/**
	 * @param hql
	 * @return
	 */
	private Query getQuery(String hql,Object[] values){
		Query query = this.getSession().createQuery(hql);
		if(values != null && values.length > 0){
			for(int i=0; i<values.length; i++){
				query.setParameter(i, values[i]);
			}
		}
		return query;
		
	}
	
	/**
	 */
	public void save(Object o){
		this.getSession().save(o);
		
	}
	/**
	 */
	
	public void deleteById(Class clazz,int objectId){
		Object o=this.getSession().get(clazz,objectId);
		delete(o);
	}
	
	public void delete(Object o){
		this.getSession().delete(o);
	}
	/**
	 */
	public void update(Object o){
		this.getSession().update(o);
	}
	
	public Object load(Class theClass,Serializable id){
       
		 return	this.getSession().load(theClass, id);
		
	}
	
	

	
	/**
	 */
	public List getResultList(String hql,Object[] values){
		
		Query query=getQuery(hql,values);
		List ls=query.list();
		
		return query.list();
		
	}
	public List getResultList(String hql,Object value){
		
		return getResultList(hql,new Object[]{value});
		
	}
	
	public List getResultList(String hql){
		
		return getResultList(hql,null);
	}
	public List getResultListSQL(String sql){
		
		return this.getSession().createSQLQuery(sql).list();
	}
	public Object getuniqueResult(String hql,Object[] values){
		
		Query query=getQuery(hql,values);
		
		return query.uniqueResult();
		
	}
	public Object getuniqueResult(String hql,Object value){
		
		return getuniqueResult(hql,new Object[]{value});
		
	}
	public Object getuniqueResult(String hql){
		
		return getuniqueResult(hql,null);
	}
	
	
}
